﻿using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;
using System.Reactive.Concurrency;
#if !WINDOWS_PHONE
using System.Threading;
using System.Threading.Tasks;
#endif

namespace System.Reactive.Linq
{
	public static partial class Qbservable
	{
		public static IQbservable<TSource> DefaultIfEmpty<TSource>(this IQbservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> DefaultIfEmpty<TSource>(this IQbservable<TSource> source, TSource defaultValue)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TValue> Defer<TValue>(this IQbservableProvider provider, Expression<Func<IObservable<TValue>>> observableFactory)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(observableFactory != null, null, "observableFactory != null");
			Contract.Ensures(Contract.Result<IQbservable<TValue>>() != null, null, "Contract.Result<IQbservable<TValue>>() != null");
			return null;
		}

#if !WINDOWS_PHONE
		public static IQbservable<TValue> DeferAsync<TValue>(this IQbservableProvider provider, Expression<Func<Task<IObservable<TValue>>>> observableFactoryAsync)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(observableFactoryAsync != null, null, "observableFactoryAsync != null");
			Contract.Ensures(Contract.Result<IQbservable<TValue>>() != null, null, "Contract.Result<IQbservable<TValue>>() != null");
			return null;
		}

		public static IQbservable<TValue> DeferAsync<TValue>(this IQbservableProvider provider, Expression<Func<CancellationToken, Task<IObservable<TValue>>>> observableFactoryAsync)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(observableFactoryAsync != null, null, "observableFactoryAsync != null");
			Contract.Ensures(Contract.Result<IQbservable<TValue>>() != null, null, "Contract.Result<IQbservable<TValue>>() != null");
			return null;
		}
#endif

		public static IQbservable<TSource> Delay<TSource, TDelay>(this IQbservable<TSource> source, Expression<Func<TSource, IObservable<TDelay>>> delayDurationSelector)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(delayDurationSelector != null, null, "delayDurationSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Delay<TSource>(this IQbservable<TSource> source, DateTimeOffset dueTime)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Delay<TSource>(this IQbservable<TSource> source, TimeSpan dueTime)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Delay<TSource, TDelay>(this IQbservable<TSource> source, IObservable<TDelay> subscriptionDelay, Expression<Func<TSource, IObservable<TDelay>>> delayDurationSelector)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(subscriptionDelay != null, null, "subscriptionDelay != null");
			Contract.Requires(delayDurationSelector != null, null, "delayDurationSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Delay<TSource>(this IQbservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Delay<TSource>(this IQbservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> DelaySubscription<TSource>(this IQbservable<TSource> source, DateTimeOffset dueTime)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> DelaySubscription<TSource>(this IQbservable<TSource> source, TimeSpan dueTime)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> DelaySubscription<TSource>(this IQbservable<TSource> source, DateTimeOffset dueTime, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> DelaySubscription<TSource>(this IQbservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Dematerialize<TSource>(this IQbservable<Notification<TSource>> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Distinct<TSource>(this IQbservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Distinct<TSource, TKey>(this IQbservable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(keySelector != null, null, "keySelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Distinct<TSource>(this IQbservable<TSource> source, IEqualityComparer<TSource> comparer)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(comparer != null, null, "comparer != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Distinct<TSource, TKey>(this IQbservable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IEqualityComparer<TKey> comparer)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(keySelector != null, null, "keySelector != null");
			Contract.Requires(comparer != null, null, "comparer != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> DistinctUntilChanged<TSource>(this IQbservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> DistinctUntilChanged<TSource, TKey>(this IQbservable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(keySelector != null, null, "keySelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> DistinctUntilChanged<TSource>(this IQbservable<TSource> source, IEqualityComparer<TSource> comparer)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(comparer != null, null, "comparer != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> DistinctUntilChanged<TSource, TKey>(this IQbservable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IEqualityComparer<TKey> comparer)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(keySelector != null, null, "keySelector != null");
			Contract.Requires(comparer != null, null, "comparer != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Do<TSource>(this IQbservable<TSource> source, Expression<Action<TSource>> onNext)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(onNext != null, null, "onNext != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Do<TSource>(this IQbservable<TSource> source, IObserver<TSource> observer)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(observer != null, null, "observer != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Do<TSource>(this IQbservable<TSource> source, Expression<Action<TSource>> onNext, Expression<Action> onCompleted)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(onNext != null, null, "onNext != null");
			Contract.Requires(onCompleted != null, null, "onCompleted != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Do<TSource>(this IQbservable<TSource> source, Expression<Action<TSource>> onNext, Expression<Action<Exception>> onError)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(onNext != null, null, "onNext != null");
			Contract.Requires(onError != null, null, "onError != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> Do<TSource>(this IQbservable<TSource> source, Expression<Action<TSource>> onNext, Expression<Action<Exception>> onError, Expression<Action> onCompleted)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(onNext != null, null, "onNext != null");
			Contract.Requires(onError != null, null, "onError != null");
			Contract.Requires(onCompleted != null, null, "onCompleted != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}

		public static IQbservable<TSource> DoWhile<TSource>(this IQbservable<TSource> source, Expression<Func<bool>> condition)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(condition != null, null, "condition != null");
			Contract.Ensures(Contract.Result<IQbservable<TSource>>() != null, null, "Contract.Result<IQbservable<TSource>>() != null");
			return null;
		}
	}
}